home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / src / winspector.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-09  |  52.8 KB  |  1,787 lines

  1. /* winspector.c - window attribute inspector
  2.  * 
  3.  *  Window Maker window manager
  4.  * 
  5.  *  Copyright (c) 1997, 1998 Alfredo K. Kojima
  6.  *  Copyright (c) 1998       Dan Pascu
  7.  * 
  8.  *  This program is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2 of the License, or
  11.  *  (at your option) any later version.
  12.  *
  13.  *  This program is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with this program; if not, write to the Free Software
  20.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  21.  *  USA.
  22.  */
  23.  
  24. #include "wconfig.h"
  25.  
  26. #include <X11/Xlib.h>
  27. #include <X11/Xutil.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31.  
  32. #include "WindowMaker.h"
  33. #include "screen.h"
  34. #include "wcore.h"
  35. #include "framewin.h"
  36. #include "window.h"
  37. #include "workspace.h"
  38. #include "funcs.h"
  39. #include "defaults.h"
  40. #include "dialog.h"
  41. #include "icon.h"
  42. #include "stacking.h"
  43. #include "application.h"
  44. #include "appicon.h"
  45. #include "actions.h"
  46. #include "winspector.h"
  47. #include "dock.h"
  48. #include "client.h"
  49.  
  50. #include <proplist.h>
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58. typedef struct InspectorPanel {
  59.     struct InspectorPanel *nextPtr;
  60.  
  61.     WWindow *frame;
  62.  
  63.     WWindow *inspected;       /* the window that's being inspected */
  64.  
  65.     WMWindow *win;
  66.     
  67.     Window parent;
  68.  
  69.     /* common stuff */
  70.     WMButton *revertBtn;
  71.     WMButton *applyBtn;
  72.     WMButton *saveBtn;
  73.  
  74.     WMPopUpButton *pagePopUp;
  75.  
  76.     /* first page. general stuff */
  77.     
  78.     WMFrame *specFrm;
  79.     WMButton *instRb;
  80.     WMButton *clsRb;
  81.     WMButton *bothRb;
  82.     WMButton *defaultRb;
  83.  
  84.     WMButton *selWinB;
  85.     
  86.     WMLabel *specLbl;
  87.     
  88.     /* second page. attributes */
  89.  
  90.     WMFrame *attrFrm;
  91.     WMButton *attrChk[11];
  92.  
  93.     /* 3rd page. more attributes */
  94.     WMFrame *moreFrm;
  95. #ifdef XKB_BUTTON_HINT
  96.     WMButton *moreChk[9];
  97. #else
  98.     WMButton *moreChk[8];
  99. #endif
  100.  
  101.     /* 4th page. icon and workspace */
  102.     WMFrame *iconFrm;
  103.     WMLabel *iconLbl;
  104.     WMLabel *fileLbl;
  105.     WMTextField *fileText;
  106.     WMButton *alwChk;
  107.     /*
  108.     WMButton *updateIconBtn;
  109.      */
  110.     WMButton *browseIconBtn;
  111.     
  112.     WMFrame *wsFrm;
  113.     WMPopUpButton *wsP;
  114.     
  115.     /* 5th page. application wide attributes */
  116.     WMFrame *appFrm;
  117.     WMButton *appChk[2];
  118.  
  119.     unsigned int done:1;
  120.     unsigned int destroyed:1;
  121.     unsigned int choosingIcon:1;
  122. } InspectorPanel;
  123.  
  124.  
  125.  
  126.  
  127. extern Cursor wCursor[WCUR_LAST];
  128.  
  129. extern WDDomain *WDWindowAttributes;
  130.  
  131. static InspectorPanel *panelList=NULL;
  132.  
  133. extern WPreferences wPreferences;
  134.  
  135. static proplist_t ANoTitlebar = NULL;
  136. static proplist_t ANoResizebar;
  137. static proplist_t ANoMiniaturizeButton;
  138. static proplist_t ANoCloseButton;
  139. static proplist_t ANoBorder;
  140. static proplist_t ANoHideOthers;
  141. static proplist_t ANoMouseBindings;
  142. static proplist_t ANoKeyBindings;
  143. static proplist_t ANoAppIcon;
  144. static proplist_t AKeepOnTop;
  145. static proplist_t AKeepOnBottom;
  146. static proplist_t AOmnipresent;
  147. static proplist_t ASkipWindowList;
  148. static proplist_t AKeepInsideScreen;
  149. static proplist_t AUnfocusable;
  150. static proplist_t AAlwaysUserIcon;
  151. static proplist_t AStartMiniaturized;
  152. static proplist_t AStartMaximized;
  153. static proplist_t ADontSaveSession;
  154. static proplist_t AEmulateAppIcon;
  155. static proplist_t AFullMaximize;
  156. #ifdef XKB_BUTTON_HINT
  157. static proplist_t ANoLanguageButton;
  158. #endif
  159.  
  160. static proplist_t AStartWorkspace;
  161.  
  162. static proplist_t AIcon;
  163.  
  164. /* application wide options */
  165. static proplist_t AStartHidden;
  166.  
  167.  
  168. static proplist_t AnyWindow;
  169. static proplist_t EmptyString;
  170. static proplist_t Yes, No;
  171.  
  172.  
  173. #define PWIDTH    270
  174. #define PHEIGHT    350
  175.  
  176.  
  177.  
  178.  
  179. static void applySettings(WMButton *button, InspectorPanel *panel);
  180.  
  181.  
  182.  
  183.  
  184. #define UNDEFINED_POS 0xffffff
  185.  
  186. static InspectorPanel *createInspectorForWindow(WWindow *wwin, 
  187.                         int xpos, int ypos,
  188.                         Bool showSelectPanel);
  189.  
  190.  
  191.  
  192. static void
  193. make_keys()
  194. {
  195.     if (ANoTitlebar!=NULL)
  196.     return;
  197.  
  198.     AIcon = PLMakeString("Icon");
  199.     ANoTitlebar = PLMakeString("NoTitlebar");
  200.     ANoResizebar = PLMakeString("NoResizebar");
  201.     ANoMiniaturizeButton = PLMakeString("NoMiniaturizeButton");
  202.     ANoCloseButton = PLMakeString("NoCloseButton");
  203.     ANoBorder = PLMakeString("NoBorder");    
  204.     ANoHideOthers = PLMakeString("NoHideOthers");
  205.     ANoMouseBindings = PLMakeString("NoMouseBindings");
  206.     ANoKeyBindings = PLMakeString("NoKeyBindings");
  207.     ANoAppIcon = PLMakeString("NoAppIcon");
  208.     AKeepOnTop = PLMakeString("KeepOnTop");
  209.     AKeepOnBottom = PLMakeString("KeepOnBottom");
  210.     AOmnipresent = PLMakeString("Omnipresent");
  211.     ASkipWindowList = PLMakeString("SkipWindowList");
  212.     AKeepInsideScreen = PLMakeString("KeepInsideScreen");
  213.     AUnfocusable = PLMakeString("Unfocusable");
  214.     AAlwaysUserIcon = PLMakeString("AlwaysUserIcon");
  215.     AStartMiniaturized = PLMakeString("StartMiniaturized");
  216.     AStartMaximized = PLMakeString("StartMaximized");
  217.     AStartHidden = PLMakeString("StartHidden");
  218.     ADontSaveSession = PLMakeString("DontSaveSession");
  219.     AEmulateAppIcon = PLMakeString("EmulateAppIcon");
  220.     AFullMaximize = PLMakeString("FullMaximize");
  221. #ifdef XKB_BUTTON_HINT
  222.     ANoLanguageButton = PLMakeString("NoLanguageButton");
  223. #endif
  224.  
  225.     AStartWorkspace = PLMakeString("StartWorkspace");
  226.  
  227.     AnyWindow = PLMakeString("*");
  228.     EmptyString = PLMakeString("");
  229.     Yes = PLMakeString("Yes");
  230.     No = PLMakeString("No");
  231. }
  232.  
  233.  
  234.  
  235. static void
  236. freeInspector(InspectorPanel *panel)
  237. {
  238.     panel->destroyed = 1;
  239.     if (panel->choosingIcon)
  240.     return;
  241.  
  242.     WMDestroyWidget(panel->win);
  243.  
  244.     XDestroyWindow(dpy, panel->parent);
  245.  
  246.     free(panel);
  247. }
  248.  
  249.  
  250. static void
  251. destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
  252. {
  253.     InspectorPanel *panel;
  254.     InspectorPanel *tmp;
  255.  
  256.     panel = panelList;
  257.     while (panel->frame!=data)
  258.     panel = panel->nextPtr;
  259.     
  260.     if (panelList == panel) 
  261.     panelList = panel->nextPtr;
  262.     else {
  263.     tmp = panelList;
  264.     while (tmp->nextPtr!=panel) {
  265.         tmp = tmp->nextPtr;
  266.     }
  267.     tmp->nextPtr = panel->nextPtr;
  268.     }
  269.     panel->inspected->flags.inspector_open = 0;
  270.     panel->inspected->inspector = NULL;
  271.  
  272.     WMRemoveNotificationObserver(panel);
  273.  
  274.     wWindowUnmap(panel->frame);
  275.     wUnmanageWindow(panel->frame, True, False);
  276.  
  277.     freeInspector(panel);
  278. }
  279.  
  280.  
  281.  
  282. void
  283. wDestroyInspectorPanels()
  284. {
  285.     InspectorPanel *panel;
  286.  
  287.     while (panelList != NULL) {
  288.         panel = panelList;
  289.         panelList = panelList->nextPtr;
  290.         wUnmanageWindow(panel->frame, False, False);
  291.         WMDestroyWidget(panel->win);
  292.  
  293.         panel->inspected->flags.inspector_open = 0;
  294.         panel->inspected->inspector = NULL;
  295.  
  296.         free(panel);
  297.     }
  298. }
  299.  
  300.  
  301. static void
  302. changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
  303. {
  304.     int page;
  305.     
  306.     page = WMGetPopUpButtonSelectedItem(bPtr);
  307.     
  308.     if (page == 0) {
  309.     WMMapWidget(panel->specFrm);
  310.     WMMapWidget(panel->specLbl);
  311.     } else if (page == 1) {
  312.     WMMapWidget(panel->attrFrm);    
  313.     } else if (page == 2) {    
  314.     WMMapWidget(panel->moreFrm);
  315.     } else if (page == 3) {
  316.     WMMapWidget(panel->iconFrm);
  317.     WMMapWidget(panel->wsFrm);
  318.     } else {
  319.     WMMapWidget(panel->appFrm);
  320.     }
  321.     
  322.     if (page != 0) {
  323.     WMUnmapWidget(panel->specFrm);
  324.     WMUnmapWidget(panel->specLbl);
  325.     }
  326.     if (page != 1)
  327.     WMUnmapWidget(panel->attrFrm);
  328.     if (page != 2)
  329.     WMUnmapWidget(panel->moreFrm);
  330.     if (page != 3) {
  331.     WMUnmapWidget(panel->iconFrm);
  332.     WMUnmapWidget(panel->wsFrm);
  333.     }
  334.     if (page != 4 && panel->appFrm)
  335.     WMUnmapWidget(panel->appFrm);
  336. }
  337.  
  338.  
  339. #define USE_TEXT_FIELD          1
  340. #define UPDATE_TEXT_FIELD       2
  341. #define REVERT_TO_DEFAULT       4
  342.  
  343.  
  344. static int
  345. showIconFor(WMScreen *scrPtr, InspectorPanel *panel,
  346.             char *wm_instance, char *wm_class, int flags)
  347. {
  348.     WMPixmap *pixmap = (WMPixmap*) NULL;
  349.     char *file=NULL, *path=NULL;
  350.     char *db_icon=NULL;
  351.  
  352.     if ((flags & USE_TEXT_FIELD) != 0) {
  353.         file = WMGetTextFieldText(panel->fileText);
  354.         if (file && file[0] == 0) {
  355.             free(file);
  356.             file = NULL;
  357.         }
  358.     } else {
  359.         db_icon = wDefaultGetIconFile(panel->inspected->screen_ptr,
  360.                                       wm_instance, wm_class, False);
  361.         if(db_icon != NULL)
  362.             file = wstrdup(db_icon);
  363.     }
  364.     if (db_icon!=NULL && (flags & REVERT_TO_DEFAULT)!=0) {
  365.     if (file)
  366.         file = wstrdup(db_icon);
  367.         flags |= UPDATE_TEXT_FIELD;
  368.     }
  369.  
  370.     if ((flags & UPDATE_TEXT_FIELD) != 0) {
  371.         WMSetTextFieldText(panel->fileText, file);
  372.     }
  373.  
  374.     if (file) {
  375.         path = FindImage(wPreferences.icon_path, file);
  376.  
  377.         if (!path) {
  378.         char *buf;
  379.         
  380.         buf = wmalloc(strlen(file)+80);
  381.         sprintf(buf, _("Could not find icon \"%s\" specified for this window"),
  382.             file);
  383.             wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, 
  384.                _("OK"), NULL, NULL);
  385.         free(buf);
  386.         free(file);
  387.             return -1;
  388.         }
  389.  
  390.         pixmap = WMCreatePixmapFromFile(scrPtr, path);
  391.         free(path);
  392.  
  393.         if (!pixmap) {
  394.         char *buf;
  395.         
  396.         buf = wmalloc(strlen(file)+80);
  397.         sprintf(buf, _("Could not open specified icon \"%s\":%s"),
  398.             file, RMessageForError(RErrorCode));
  399.             wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
  400.                _("OK"), NULL, NULL);
  401.         free(buf);
  402.         free(file);
  403.             return -1;
  404.         }
  405.         free(file);
  406.     }
  407.  
  408.     WMSetLabelImage(panel->iconLbl, pixmap);
  409.     if (pixmap)
  410.         WMReleasePixmap(pixmap);
  411.  
  412.     return 0;
  413. }
  414.  
  415. #if 0
  416. static void
  417. updateIcon(WMButton *button, InspectorPanel *panel)
  418. {
  419.     showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
  420. }
  421. #endif
  422.  
  423. static int 
  424. getBool(proplist_t value)
  425. {
  426.     char *val;
  427.  
  428.     if (!PLIsString(value)) {
  429.         return 0;
  430.     }
  431.     if (!(val = PLGetString(value))) {
  432.         return 0;
  433.     }
  434.  
  435.     if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y' || val[0]=='T'
  436.                           || val[0]=='t' || val[0]=='1'))
  437.         || (strcasecmp(val, "YES")==0 || strcasecmp(val, "TRUE")==0)) {
  438.  
  439.         return 1;
  440.     } else if ((val[1]=='\0'
  441.                 && (val[0]=='n' || val[0]=='N' || val[0]=='F'
  442.                     || val[0]=='f' || val[0]=='0'))
  443.                || (strcasecmp(val, "NO")==0 || strcasecmp(val, "FALSE")==0)) {
  444.  
  445.         return 0;
  446.     } else {
  447.         wwarning(_("can't convert \"%s\" to boolean"), val);
  448.         return 0;
  449.     }
  450. }
  451.  
  452.  
  453. #define UPDATE_DEFAULTS    1
  454. #define IS_BOOLEAN         2
  455.  
  456.  
  457. /*
  458.  *  Will insert the attribute = value; pair in window's list,
  459.  * if it's different from the defaults.
  460.  *  Defaults means either defaults database, or attributes saved
  461.  * for the default window "*". This is to let one revert options that are
  462.  * global because they were saved for all windows ("*").
  463.  *
  464.  */
  465.  
  466.  
  467. static int
  468. insertAttribute(proplist_t dict, proplist_t window, proplist_t attr,
  469.                 proplist_t value, int flags)
  470. {
  471.     proplist_t def_win, def_value=NULL;
  472.     int update = 0;
  473.     int modified = 0;
  474.  
  475.     if (!(flags & UPDATE_DEFAULTS) && dict) {
  476.         if ((def_win = PLGetDictionaryEntry(dict, AnyWindow)) != NULL) {
  477.             def_value = PLGetDictionaryEntry(def_win, attr);
  478.         }
  479.     }
  480.  
  481.     /* If we could not find defaults in database, fall to hardcoded values.
  482.      * Also this is true if we save defaults for all windows
  483.      */
  484.     if (!def_value)
  485.         def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
  486.  
  487.     if ((flags & IS_BOOLEAN))
  488.         update = (getBool(value) != getBool(def_value));
  489.     else {
  490.         update = !PLIsEqual(value, def_value);
  491.     }
  492.  
  493.     if (update) {
  494.         PLInsertDictionaryEntry(window, attr, value);
  495.         modified = 1;
  496.     }
  497.  
  498.     return modified;
  499. }
  500.  
  501.  
  502. static void
  503. saveSettings(WMButton *button, InspectorPanel *panel)
  504. {
  505.     WWindow *wwin = panel->inspected;
  506.     WDDomain *db = WDWindowAttributes;
  507.     proplist_t dict = db->dictionary;
  508.     proplist_t winDic, value, key;
  509.     char *icon_file;
  510.     int flags = 0;
  511.     int different = 0;
  512.  
  513.     /* Save will apply the changes and save them */
  514.     applySettings(panel->applyBtn, panel);
  515.     
  516.     if (WMGetButtonSelected(panel->instRb) != 0)
  517.         key = PLMakeString(wwin->wm_instance);
  518.     else if (WMGetButtonSelected(panel->clsRb) != 0)
  519.         key = PLMakeString(wwin->wm_class);
  520.     else if (WMGetButtonSelected(panel->bothRb) != 0) {
  521.         char *buffer;
  522.  
  523.         buffer = wmalloc(strlen(wwin->wm_instance)+strlen(wwin->wm_class)+4);
  524.         strcat(strcat(strcpy(buffer, wwin->wm_instance), "."), wwin->wm_class);
  525.         key = PLMakeString(buffer);
  526.         free(buffer);
  527.     } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
  528.         key = PLRetain(AnyWindow);
  529.         flags = UPDATE_DEFAULTS;
  530.     } else
  531.         key = NULL;
  532.  
  533.     if (!key)
  534.         return;
  535.  
  536.     if (!dict) {
  537.         dict = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
  538.         if (dict) {
  539.             db->dictionary = dict;
  540.             value = PLMakeString(db->path);
  541.             PLSetFilename(dict, value);
  542.             PLRelease(value);
  543.         }
  544.         else {
  545.             PLRelease(key);
  546.             return;
  547.         }
  548.     }
  549.  
  550.     if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL,
  551.             USE_TEXT_FIELD) < 0)
  552.         return;
  553.  
  554.     PLSetStringCmpHook(NULL);
  555.  
  556.     winDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
  557.  
  558.     /* Update icon for window */
  559.     icon_file = WMGetTextFieldText(panel->fileText);
  560.     if (icon_file) {
  561.         if (icon_file[0] != 0) {
  562.             value = PLMakeString(icon_file);
  563.             different |= insertAttribute(dict, winDic, AIcon, value, flags);
  564.             PLRelease(value);
  565.         }
  566.         free(icon_file);
  567.     }
  568.  
  569.     {
  570.     int i = WMGetPopUpButtonSelectedItem(panel->wsP);
  571.  
  572.     i--;
  573.  
  574.     if (i>=0 && i < panel->frame->screen_ptr->workspace_count) {
  575.         value = PLMakeString(panel->frame->screen_ptr->workspaces[i]->name);
  576.         different |= insertAttribute(dict, winDic, AStartWorkspace, value, 
  577.                      flags);
  578.         PLRelease(value);
  579.         }
  580.     }
  581.  
  582.     flags |= IS_BOOLEAN;
  583.  
  584.     value = (WMGetButtonSelected(panel->alwChk)!=0) ? Yes : No;
  585.     different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
  586.  
  587.     value = (WMGetButtonSelected(panel->attrChk[0])!=0) ? Yes : No;
  588.     different |= insertAttribute(dict, winDic, ANoTitlebar,     value, flags);
  589.  
  590.     value = (WMGetButtonSelected(panel->attrChk[1])!=0) ? Yes : No;
  591.     different |= insertAttribute(dict, winDic, ANoResizebar,     value, flags);
  592.  
  593.     value = (WMGetButtonSelected(panel->attrChk[2])!=0) ? Yes : No;
  594.     different |= insertAttribute(dict, winDic, ANoCloseButton,   value, flags);
  595.  
  596.     value = (WMGetButtonSelected(panel->attrChk[3])!=0) ? Yes : No;
  597.     different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
  598.  
  599.     value = (WMGetButtonSelected(panel->attrChk[4])!=0) ? Yes : No;
  600.     different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
  601.  
  602.     value = (WMGetButtonSelected(panel->attrChk[5])!=0) ? Yes : No;
  603.     different |= insertAttribute(dict, winDic, AKeepOnTop,       value, flags);
  604.  
  605.     value = (WMGetButtonSelected(panel->attrChk[6])!=0) ? Yes : No;
  606.     different |= insertAttribute(dict, winDic, AKeepOnBottom,    value, flags);
  607.  
  608.     value = (WMGetButtonSelected(panel->attrChk[7])!=0) ? Yes : No;
  609.     different |= insertAttribute(dict, winDic, AOmnipresent,     value, flags);
  610.  
  611.     value = (WMGetButtonSelected(panel->attrChk[8])!=0) ? Yes : No;
  612.     different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
  613.  
  614.     value = (WMGetButtonSelected(panel->attrChk[9])!=0) ? Yes : No;
  615.     different |= insertAttribute(dict, winDic, AStartMaximized,  value, flags);
  616.  
  617.     value = (WMGetButtonSelected(panel->attrChk[10])!=0) ? Yes : No;
  618.     different |= insertAttribute(dict, winDic, ASkipWindowList,  value, flags);
  619.  
  620.  
  621.     value = (WMGetButtonSelected(panel->moreChk[0])!=0) ? Yes : No;
  622.     different |= insertAttribute(dict, winDic, ANoHideOthers,    value, flags);
  623.  
  624.     value = (WMGetButtonSelected(panel->moreChk[1])!=0) ? Yes : No;
  625.     different |= insertAttribute(dict, winDic, ANoKeyBindings,   value, flags);
  626.  
  627.     value = (WMGetButtonSelected(panel->moreChk[2])!=0) ? Yes : No;
  628.     different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
  629.  
  630.     value = (WMGetButtonSelected(panel->moreChk[3])!=0) ? Yes : No;
  631.     different |= insertAttribute(dict, winDic, AKeepInsideScreen,value, flags);
  632.  
  633.     value = (WMGetButtonSelected(panel->moreChk[4])!=0) ? Yes : No;
  634.     different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
  635.  
  636.     value = (WMGetButtonSelected(panel->moreChk[5])!=0) ? Yes : No;
  637.     different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
  638.  
  639.     value = (WMGetButtonSelected(panel->moreChk[6])!=0) ? Yes : No;
  640.     different |= insertAttribute(dict, winDic, AEmulateAppIcon,  value, flags);
  641.  
  642.     value = (WMGetButtonSelected(panel->moreChk[7])!=0) ? Yes : No;
  643.     different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
  644.  
  645. #ifdef XKB_BUTTON_HINT
  646.     value = (WMGetButtonSelected(panel->moreChk[8])!=0) ? Yes : No;
  647.     different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
  648. #endif
  649.  
  650.     /* application wide settings for when */
  651.     /* the window is the leader, save the attribute with the others */
  652.     if (panel->inspected->main_window == panel->inspected->client_win) {
  653.     
  654.     value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
  655.     different |= insertAttribute(dict, winDic, AStartHidden, value, flags);
  656.  
  657.     value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
  658.     different |= insertAttribute(dict, winDic, ANoAppIcon, value, flags);
  659.     } 
  660.  
  661.     PLRemoveDictionaryEntry(dict, key);
  662.     if (different) {
  663.         PLInsertDictionaryEntry(dict, key, winDic);
  664.     }
  665.  
  666.     PLRelease(key); 
  667.     PLRelease(winDic);
  668.  
  669.     different = 0;
  670.     
  671.     /* application wide settings */
  672.     if (panel->inspected->main_window != panel->inspected->client_win
  673.     && !(flags & UPDATE_DEFAULTS)) {
  674.     WApplication *wapp;
  675.     proplist_t appDic;
  676.  
  677.     wapp = wApplicationOf(panel->inspected->main_window);
  678.     if (wapp) {
  679.         char *iconFile;
  680.         char *buffer;
  681.  
  682.         appDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
  683.  
  684.         assert(wapp->main_window_desc->wm_instance!=NULL);
  685.         assert(wapp->main_window_desc->wm_class!=NULL);
  686.  
  687.         buffer = wmalloc(strlen(wapp->main_window_desc->wm_instance)
  688.                          +strlen(wapp->main_window_desc->wm_class)+4);
  689.         strcat(strcpy(buffer, wapp->main_window_desc->wm_instance), ".");
  690.         strcat(buffer, wapp->main_window_desc->wm_class);
  691.         key = PLMakeString(buffer);
  692.         free(buffer);
  693.  
  694.         iconFile = wDefaultGetIconFile(wwin->screen_ptr, 
  695.                        wapp->main_window_desc->wm_instance,
  696.                        wapp->main_window_desc->wm_class,
  697.                        False);
  698.  
  699.         if (iconFile && iconFile[0]!=0) {
  700.         value = PLMakeString(iconFile);
  701.         different |= insertAttribute(dict, appDic, AIcon, value,
  702.                          flags&~IS_BOOLEAN);
  703.         PLRelease(value);
  704.         }
  705.         
  706.         value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
  707.         different |= insertAttribute(dict, appDic, AStartHidden,  value, 
  708.                      flags);
  709.  
  710.         value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
  711.         different |= insertAttribute(dict, appDic, ANoAppIcon,  value, 
  712.                      flags);
  713.  
  714.         PLRemoveDictionaryEntry(dict, key);
  715.         if (different) {
  716.         PLInsertDictionaryEntry(dict, key, appDic);
  717.         }
  718.         PLRelease(key);
  719.         PLRelease(appDic);
  720.     }
  721.     }
  722.  
  723.     PLSave(dict, YES);
  724.  
  725.     /* clean up */
  726.     PLSetStringCmpHook(StringCompareHook);
  727. }
  728.  
  729.  
  730. static void
  731. makeAppIconFor(WApplication *wapp)
  732. {
  733.     WScreen *scr = wapp->main_window_desc->screen_ptr;
  734.  
  735.     if (wapp->app_icon)
  736.         return;
  737.  
  738.     if (!WFLAGP(wapp->main_window_desc, no_appicon))
  739.         wapp->app_icon = wAppIconCreate(wapp->main_window_desc);
  740.     else
  741.         wapp->app_icon = NULL;
  742.  
  743.     if (wapp->app_icon) {
  744.         WIcon *icon = wapp->app_icon->icon;
  745.         WDock *clip = scr->workspaces[scr->current_workspace]->clip;
  746.         int x=0, y=0;
  747.  
  748.         wapp->app_icon->main_window = wapp->main_window;
  749.  
  750.         if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) {
  751.             wapp->app_icon->attracted = 1;
  752.         if (!wapp->app_icon->icon->shadowed) {
  753.         wapp->app_icon->icon->shadowed = 1;
  754.         wapp->app_icon->icon->force_paint = 1;
  755.         }
  756.             wDockAttachIcon(clip, wapp->app_icon, x, y);
  757.         } else {
  758.             PlaceIcon(scr, &x, &y);
  759.         wAppIconMove(wapp->app_icon, x, y);
  760.         }
  761.         if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
  762.         XMapWindow(dpy, icon->core->window);
  763.  
  764.         if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
  765.             wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
  766.     }
  767. }
  768.  
  769.  
  770. static void
  771. removeAppIconFor(WApplication *wapp)
  772. {
  773.     if (!wapp->app_icon)
  774.         return;
  775.  
  776.     if (wapp->app_icon->docked && !wapp->app_icon->attracted) {
  777.         wapp->app_icon->running = 0;
  778.         /* since we keep it, we don't care if it was attracted or not */
  779.         wapp->app_icon->attracted = 0;
  780.     wapp->app_icon->icon->shadowed = 0;
  781.         wapp->app_icon->main_window = None;
  782.         wapp->app_icon->pid = 0;
  783.         wapp->app_icon->icon->owner = NULL;
  784.         wapp->app_icon->icon->icon_win = None;
  785.         wapp->app_icon->icon->force_paint = 1;
  786.         wAppIconPaint(wapp->app_icon);
  787.     } else if (wapp->app_icon->docked) {
  788.         wapp->app_icon->running = 0;
  789.         wDockDetach(wapp->app_icon->dock, wapp->app_icon);
  790.     } else {
  791.         wAppIconDestroy(wapp->app_icon);
  792.     }
  793.     wapp->app_icon = NULL;
  794.     if (wPreferences.auto_arrange_icons)
  795.         wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
  796. }
  797.  
  798.  
  799. static void
  800. applySettings(WMButton *button, InspectorPanel *panel)
  801. {
  802.     WWindow *wwin = panel->inspected;
  803.     WApplication *wapp = wApplicationOf(wwin->main_window);
  804.     int floating, sunken, skip_window_list;
  805.     int old_omnipresent;
  806.     int old_no_bind_keys;
  807.     int old_no_bind_mouse;
  808.  
  809.     old_omnipresent = WFLAGP(wwin, omnipresent);
  810.     old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
  811.     old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
  812.  
  813.     showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
  814.  
  815.     WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
  816.     WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
  817.     WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
  818.     WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
  819.     WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
  820.     floating                   =  WMGetButtonSelected(panel->attrChk[5]);
  821.     sunken                     =  WMGetButtonSelected(panel->attrChk[6]);
  822.     WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
  823.     WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
  824.     WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
  825.     skip_window_list           =  WMGetButtonSelected(panel->attrChk[10]);
  826.  
  827.     WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[0]));
  828.     WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[1]));
  829.     WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[2]));
  830.     WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[3]));
  831.     WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
  832.     WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[5]));
  833.     WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[6]));
  834.     WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->moreChk[7]));
  835. #ifdef XKB_BUTTON_HINT
  836.     WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[8]));
  837. #endif
  838.     WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
  839.  
  840.     if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
  841.         wUnshadeWindow(wwin);
  842.  
  843.     WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
  844.  
  845.     if (floating) {
  846.     if (!WFLAGP(wwin, floating))
  847.         ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
  848.     } else if (sunken) {
  849.     if (!WFLAGP(wwin, sunken))
  850.         ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
  851.     } else {
  852.     if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
  853.         ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
  854.     }
  855.  
  856.     WSETUFLAG(wwin, sunken, sunken);
  857.     WSETUFLAG(wwin, floating, floating);
  858.     wwin->flags.omnipresent = 0;
  859.  
  860.     if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
  861.     WSETUFLAG(wwin, skip_window_list, skip_window_list);
  862.         UpdateSwitchMenu(wwin->screen_ptr, wwin, 
  863.              skip_window_list ? ACTION_REMOVE : ACTION_ADD);
  864.     } else {
  865.     if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
  866.         UpdateSwitchMenu(wwin->screen_ptr, wwin, ACTION_CHANGE_WORKSPACE);
  867.     }
  868.     }
  869.     
  870.     if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
  871.     if (WFLAGP(wwin, no_bind_keys)) {
  872.         XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
  873.     } else {
  874.         wWindowSetKeyGrabs(wwin);
  875.     }
  876.     }
  877.     
  878.     if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
  879.     wWindowResetMouseGrabs(wwin);
  880.     }
  881.  
  882.     wwin->frame->flags.need_texture_change = 1;
  883.     wWindowConfigureBorders(wwin);
  884.     wFrameWindowPaint(wwin->frame);
  885.  
  886.     /*
  887.      * Can't apply emulate_appicon because it will probably cause problems.
  888.      */
  889.     
  890.     if (wapp) {
  891.     /* do application wide stuff */
  892.     WSETUFLAG(wapp->main_window_desc, start_hidden,
  893.           WMGetButtonSelected(panel->appChk[0]));
  894.  
  895.     WSETUFLAG(wapp->main_window_desc, no_appicon,
  896.           WMGetButtonSelected(panel->appChk[1]));
  897.     
  898.         if (WFLAGP(wapp->main_window_desc, no_appicon))
  899.             removeAppIconFor(wapp);
  900.     else
  901.             makeAppIconFor(wapp);
  902.  
  903.         if (wapp->app_icon && wapp->main_window == wwin->client_win) {
  904.             char *file = WMGetTextFieldText(panel->fileText);
  905.  
  906.         if (file[0] == 0) {
  907.         free(file);
  908.         file = NULL;
  909.         }
  910.         wIconChangeImageFile(wapp->app_icon->icon, file);
  911.         if (file)
  912.         free(file);
  913.         wAppIconPaint(wapp->app_icon);
  914.         }
  915.     }
  916. }
  917.  
  918.  
  919.  
  920.  
  921. static void
  922. revertSettings(WMButton *button, InspectorPanel *panel)
  923. {
  924.     WWindow *wwin = panel->inspected;
  925.     WApplication *wapp = wApplicationOf(wwin->main_window);
  926.     int i, n;
  927.     char *wm_instance = NULL;
  928.     char *wm_class = NULL;
  929.     int workspace, level;
  930.  
  931.     if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
  932.         wm_instance = wwin->wm_instance;
  933.     else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
  934.         wm_class = wwin->wm_class;
  935.     else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
  936.         wm_instance = wwin->wm_instance;
  937.         wm_class = wwin->wm_class;
  938.     }
  939.     memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
  940.     memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
  941.     memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
  942.  
  943.     wWindowSetupInitialAttributes(wwin, &level, &workspace);
  944.  
  945.     for (i=0; i < 11; i++) {
  946.     int flag = 0;
  947.     
  948.     switch (i) {
  949.      case 0:
  950.             flag = WFLAGP(wwin, no_titlebar);
  951.         break;
  952.      case 1:
  953.         flag = WFLAGP(wwin, no_resizebar);
  954.         break;
  955.      case 2:
  956.         flag = WFLAGP(wwin, no_close_button);
  957.         break;
  958.      case 3:
  959.         flag = WFLAGP(wwin, no_miniaturize_button);
  960.         break;
  961.      case 4:
  962.         flag = WFLAGP(wwin, no_border);
  963.         break;
  964.      case 5:
  965.             flag = WFLAGP(wwin, floating);
  966.         break;
  967.      case 6:
  968.             flag = WFLAGP(wwin, sunken);
  969.         break;
  970.      case 7:
  971.         flag = WFLAGP(wwin, omnipresent);
  972.         break;
  973.      case 8:
  974.         flag = WFLAGP(wwin, start_miniaturized);
  975.         break;
  976.      case 9:
  977.         flag = WFLAGP(wwin, start_maximized!=0);
  978.         break;
  979.      case 10:
  980.         flag = WFLAGP(wwin, skip_window_list);
  981.         break;
  982.     }
  983.         WMSetButtonSelected(panel->attrChk[i], flag);
  984.     }
  985.     for (i=0; i < 8; i++) {
  986.     int flag = 0;
  987.     
  988.     switch (i) {
  989.      case 0:
  990.         flag = WFLAGP(wwin, no_hide_others);
  991.         break;
  992.      case 1:
  993.         flag = WFLAGP(wwin, no_bind_keys);
  994.         break;
  995.      case 2:
  996.         flag = WFLAGP(wwin, no_bind_mouse);
  997.         break;
  998.      case 3:
  999.         flag = WFLAGP(wwin, dont_move_off);
  1000.         break;
  1001.      case 4:
  1002.         flag = WFLAGP(wwin, no_focusable);
  1003.         break;
  1004.      case 5:
  1005.         flag = WFLAGP(wwin, dont_save_session);
  1006.         break;
  1007.      case 6:
  1008.         flag = WFLAGP(wwin, emulate_appicon);
  1009.         break;
  1010.      case 7:
  1011.         flag = WFLAGP(wwin, full_maximize);
  1012.         break;
  1013. #ifdef XKB_BUTTON_HINT
  1014.      case 8:
  1015.         flag = WFLAGP(wwin, no_language_button);
  1016.         break;
  1017. #endif
  1018.     }
  1019.     WMSetButtonSelected(panel->moreChk[i], flag);
  1020.     }
  1021.     if (panel->appFrm && wapp) {
  1022.     for (i=0; i < 2; i++) {
  1023.         int flag = 0;
  1024.         
  1025.         switch (i) {
  1026.          case 0:
  1027.         flag = WFLAGP(wapp->main_window_desc, start_hidden);
  1028.         break;
  1029.          case 1:
  1030.         flag = WFLAGP(wapp->main_window_desc, no_appicon);
  1031.         break;
  1032.         }
  1033.         WMSetButtonSelected(panel->appChk[i], flag);
  1034.     }
  1035.     }
  1036.     WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
  1037.  
  1038.     showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class,
  1039.         REVERT_TO_DEFAULT);
  1040.  
  1041.     n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
  1042.  
  1043.     if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
  1044.     WMSetPopUpButtonSelectedItem(panel->wsP, n+1);
  1045.     } else {
  1046.     WMSetPopUpButtonSelectedItem(panel->wsP, 0);
  1047.     }
  1048.     
  1049.     /* must auto apply, so that there wno't be internal
  1050.      * inconsistencies between the state in the flags and
  1051.      * the actual state of the window */
  1052.     applySettings(panel->applyBtn, panel);
  1053. }
  1054.  
  1055.  
  1056. static void
  1057. chooseIconCallback(WMWidget *self, void *clientData)
  1058. {
  1059.     char *file;
  1060.     InspectorPanel *panel = (InspectorPanel*)clientData;
  1061.     int result;
  1062.  
  1063.     panel->choosingIcon = 1;
  1064.     
  1065.     WMSetButtonEnabled(panel->browseIconBtn, False);
  1066.     
  1067.     result = wIconChooserDialog(panel->frame->screen_ptr, &file,
  1068.                 panel->inspected->wm_instance,
  1069.                 panel->inspected->wm_class);
  1070.     
  1071.     panel->choosingIcon = 0;
  1072.  
  1073.     if (!panel->destroyed) { /* kluge */    
  1074.     if (result) {        
  1075.         WMSetTextFieldText(panel->fileText, file);
  1076.         showIconFor(WMWidgetScreen(self), panel, NULL, NULL,
  1077.             USE_TEXT_FIELD);
  1078.         free(file);
  1079.     }
  1080.     WMSetButtonEnabled(panel->browseIconBtn, True);
  1081.     } else {
  1082.     freeInspector(panel);
  1083.     }
  1084. }
  1085.  
  1086.  
  1087. static void
  1088. textEditedObserver(void *observerData, WMNotification *notification)
  1089. {
  1090.     InspectorPanel *panel = (InspectorPanel*)observerData;
  1091.  
  1092.     if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
  1093.     return;
  1094.  
  1095.     showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, 
  1096.         USE_TEXT_FIELD);
  1097.     /*
  1098.      WMPerformButtonClick(panel->updateIconBtn);
  1099.      */
  1100. }
  1101.  
  1102.  
  1103. static void
  1104. selectSpecification(WMWidget *bPtr, void *data)
  1105. {
  1106.     InspectorPanel *panel = (InspectorPanel*)data;
  1107.     char *str;
  1108.     WWindow *wwin = panel->inspected;
  1109.  
  1110.  
  1111.     if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class)) {
  1112.     WMSetButtonEnabled(panel->applyBtn, False);
  1113.     } else {
  1114.     WMSetButtonEnabled(panel->applyBtn, True);
  1115.     }
  1116.  
  1117.     str = wmalloc(16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
  1118.           + strlen(wwin->wm_class ? wwin->wm_class : "?"));
  1119.  
  1120.     sprintf(str, "Inspecting  %s.%s",
  1121.         wwin->wm_instance ? wwin->wm_instance : "?",
  1122.         wwin->wm_class ? wwin->wm_class : "?");
  1123.  
  1124.     wFrameWindowChangeTitle(panel->frame->frame, str);
  1125.  
  1126.     free(str);
  1127. }
  1128.  
  1129.  
  1130.  
  1131.  
  1132. #define SPEC_TEXT "The configuration will apply to all\n"\
  1133.              "windows that have their WM_CLASS property"\
  1134.              " set to the above selected\nname, when saved."
  1135.  
  1136.  
  1137. #define SELEC_TEXT "Click in the window you wish to inspect."
  1138.  
  1139.  
  1140.  
  1141. static void
  1142. selectWindow(WMWidget *bPtr, void *data)
  1143. {
  1144.     InspectorPanel *panel = (InspectorPanel*)data;
  1145.     WWindow *wwin = panel->inspected;
  1146.     WScreen *scr = wwin->screen_ptr;
  1147.     XEvent event;
  1148.     WWindow *iwin;
  1149.     
  1150.     if (XGrabPointer(dpy, scr->root_win, True,
  1151.              ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
  1152.              wCursor[WCUR_SELECT], CurrentTime)!=GrabSuccess) {
  1153.     wwarning("could not grab mouse pointer");
  1154.     return;
  1155.     }
  1156.     
  1157.     WMSetLabelText(panel->specLbl, _(SELEC_TEXT));
  1158.  
  1159.     WMMaskEvent(dpy, ButtonPressMask, &event);
  1160.  
  1161.     XUngrabPointer(dpy, CurrentTime);
  1162.  
  1163.     iwin = wWindowFor(event.xbutton.subwindow);
  1164.     
  1165.     if (iwin && !iwin->flags.internal_window && iwin != wwin
  1166.     && !iwin->flags.inspector_open) {
  1167.  
  1168.     iwin->flags.inspector_open = 1;
  1169.     iwin->inspector = createInspectorForWindow(iwin,
  1170.                            panel->frame->frame_x,
  1171.                            panel->frame->frame_y,
  1172.                            True);
  1173.     wCloseInspectorForWindow(wwin);
  1174.     } else {
  1175.     WMSetLabelText(panel->specLbl, _(SPEC_TEXT));
  1176.     }
  1177. }
  1178.  
  1179.  
  1180.  
  1181. static InspectorPanel*
  1182. createInspectorForWindow(WWindow *wwin, int xpos, int ypos, 
  1183.              Bool showSelectPanel)
  1184. {
  1185.     WScreen *scr = wwin->screen_ptr;
  1186.     InspectorPanel *panel;
  1187.     Window parent;
  1188.     int i;
  1189.     int x, y;
  1190.     int btn_width, frame_width;
  1191.     WMButton *selectedBtn = NULL;
  1192. #ifdef wrong_behaviour
  1193.     WMPixmap *pixmap;
  1194. #endif
  1195.  
  1196.  
  1197.     panel = wmalloc(sizeof(InspectorPanel));
  1198.     memset(panel, 0, sizeof(InspectorPanel));
  1199.     
  1200.     panel->destroyed = 0;
  1201.  
  1202.     
  1203.     panel->inspected = wwin;
  1204.  
  1205.     panel->nextPtr = panelList;
  1206.     panelList = panel;
  1207.  
  1208.  
  1209.     panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
  1210.     WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
  1211.     
  1212.  
  1213.     /**** create common stuff ****/
  1214.  
  1215.     /* command buttons */
  1216.     /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
  1217.     btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
  1218.     panel->saveBtn = WMCreateCommandButton(panel->win);
  1219.     WMSetButtonAction(panel->saveBtn, (WMAction*)saveSettings, panel);
  1220.     WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, 310);
  1221.     WMSetButtonText(panel->saveBtn, _("Save"));
  1222.     WMResizeWidget(panel->saveBtn, btn_width, 28);
  1223.     if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
  1224.     WMSetButtonEnabled(panel->saveBtn, False);
  1225.  
  1226.     panel->applyBtn = WMCreateCommandButton(panel->win);
  1227.     WMSetButtonAction(panel->applyBtn, (WMAction*)applySettings, panel);
  1228.     WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
  1229.     WMSetButtonText(panel->applyBtn, _("Apply"));
  1230.     WMResizeWidget(panel->applyBtn, btn_width, 28);
  1231.  
  1232.     panel->revertBtn = WMCreateCommandButton(panel->win);
  1233.     WMSetButtonAction(panel->revertBtn, (WMAction*)revertSettings, panel);
  1234.     WMMoveWidget(panel->revertBtn, 15, 310);
  1235.     WMSetButtonText(panel->revertBtn, _("Reload"));
  1236.     WMResizeWidget(panel->revertBtn, btn_width, 28);
  1237.  
  1238.     /* page selection popup button */
  1239.     panel->pagePopUp = WMCreatePopUpButton(panel->win);
  1240.     WMSetPopUpButtonAction(panel->pagePopUp, (WMAction*)changePage, panel);
  1241.     WMMoveWidget(panel->pagePopUp, 25, 15);
  1242.     WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
  1243.  
  1244.     WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
  1245.     WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
  1246.     WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
  1247.     WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
  1248.     WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
  1249.  
  1250.     /**** window spec ****/
  1251.     frame_width = PWIDTH - (2 * 15);
  1252.  
  1253.     panel->specFrm = WMCreateFrame(panel->win);
  1254.     WMSetFrameTitle(panel->specFrm, _("Window Specification"));
  1255.     WMMoveWidget(panel->specFrm, 15, 65);
  1256.     WMResizeWidget(panel->specFrm, frame_width, 145);
  1257.  
  1258.  
  1259.     panel->defaultRb = WMCreateRadioButton(panel->specFrm);
  1260.     WMMoveWidget(panel->defaultRb, 10, 78);
  1261.     WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
  1262.     WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
  1263.     WMSetButtonSelected(panel->defaultRb, False);
  1264.     WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
  1265.  
  1266.     if (wwin->wm_class && wwin->wm_instance) {
  1267.     char *str, *tmp;
  1268.  
  1269.         tmp = wstrappend(wwin->wm_instance, ".");
  1270.         str = wstrappend(tmp, wwin->wm_class);
  1271.  
  1272.     panel->bothRb = WMCreateRadioButton(panel->specFrm);
  1273.     WMMoveWidget(panel->bothRb, 10, 18);
  1274.     WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
  1275.     WMSetButtonText(panel->bothRb, str);
  1276.         free(tmp);
  1277.         free(str);
  1278.     WMGroupButtons(panel->defaultRb, panel->bothRb);
  1279.  
  1280.     if (!selectedBtn)
  1281.         selectedBtn = panel->bothRb;
  1282.  
  1283.     WMSetButtonAction(panel->bothRb, selectSpecification, panel);
  1284.     }
  1285.  
  1286.     if (wwin->wm_instance) {
  1287.     panel->instRb = WMCreateRadioButton(panel->specFrm);
  1288.     WMMoveWidget(panel->instRb, 10, 38);
  1289.     WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
  1290.     WMSetButtonText(panel->instRb, wwin->wm_instance);
  1291.     WMGroupButtons(panel->defaultRb, panel->instRb);
  1292.  
  1293.     if (!selectedBtn)
  1294.         selectedBtn = panel->instRb;
  1295.  
  1296.     WMSetButtonAction(panel->instRb, selectSpecification, panel);
  1297.     }
  1298.  
  1299.     if (wwin->wm_class) {
  1300.     panel->clsRb = WMCreateRadioButton(panel->specFrm);
  1301.     WMMoveWidget(panel->clsRb, 10, 58);
  1302.     WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
  1303.     WMSetButtonText(panel->clsRb, wwin->wm_class);
  1304.     WMGroupButtons(panel->defaultRb, panel->clsRb);
  1305.  
  1306.     if (!selectedBtn)
  1307.         selectedBtn = panel->clsRb;
  1308.  
  1309.     WMSetButtonAction(panel->clsRb, selectSpecification, panel);
  1310.     }
  1311.  
  1312.     
  1313.     panel->selWinB = WMCreateCommandButton(panel->specFrm);
  1314.     WMMoveWidget(panel->selWinB, 20, 145-24 - 10);
  1315.     WMResizeWidget(panel->selWinB, frame_width - 2*10 - 20, 24);
  1316.     WMSetButtonText(panel->selWinB, _("Select Window"));
  1317.     WMSetButtonAction(panel->selWinB, selectWindow, panel);
  1318.     
  1319.     
  1320.     panel->specLbl = WMCreateLabel(panel->win);
  1321.     WMMoveWidget(panel->specLbl, 15, 210);
  1322.     WMResizeWidget(panel->specLbl, frame_width, 100);
  1323.     WMSetLabelText(panel->specLbl, _(SPEC_TEXT));
  1324.     
  1325.     WMSetLabelTextAlignment(panel->specLbl, WACenter);
  1326.     
  1327.     /**** attributes ****/
  1328.     panel->attrFrm = WMCreateFrame(panel->win);
  1329.     WMSetFrameTitle(panel->attrFrm, _("Attributes"));
  1330.     WMMoveWidget(panel->attrFrm, 15, 45);
  1331.     WMResizeWidget(panel->attrFrm, frame_width, 250);
  1332.  
  1333.     for (i=0; i < 11; i++) {
  1334.     char *caption = NULL;
  1335.     int flag = 0;
  1336.     char *descr = NULL;
  1337.  
  1338.     switch (i) {
  1339.      case 0:
  1340.         caption = _("Disable Titlebar");
  1341.             flag = WFLAGP(wwin, no_titlebar);
  1342.         descr = _("Remove the titlebar of this window.\n"
  1343.               "To access the window commands menu of a window\n"
  1344.               "without it's titlebar, press Control+Esc (or the\n"
  1345.               "equivalent shortcut, if you changed the default\n"
  1346.               "settings).");
  1347.         break;
  1348.      case 1:
  1349.         caption = _("Disable Resizebar");
  1350.         flag = WFLAGP(wwin, no_resizebar);
  1351.         descr = _("Remove the resizebar of this window."); 
  1352.         break;
  1353.      case 2:
  1354.         caption = _("Disable Close Button");
  1355.         flag = WFLAGP(wwin, no_close_button);
  1356.         descr = _("Remove the `close window' button of this window.");
  1357.         break;
  1358.      case 3:
  1359.         caption = _("Disable Miniaturize Button");
  1360.         flag = WFLAGP(wwin, no_miniaturize_button);
  1361.         descr = _("Remove the `miniaturize window' button of the window.");
  1362.         break;
  1363.      case 4:
  1364.         caption = _("Disable Border");
  1365.         flag = WFLAGP(wwin, no_border);
  1366.         descr = _("Remove the 1 pixel black border around the window.");
  1367.         break;
  1368.      case 5:
  1369.         caption = _("Keep on Top / Floating");
  1370.         flag = WFLAGP(wwin, floating);
  1371.         descr = _("Keep the window over other windows, not allowing\n"
  1372.               "them to covert it.");
  1373.         break;
  1374.      case 6:
  1375.         caption = _("Keep at Bottom / Sunken");
  1376.         flag = WFLAGP(wwin, sunken);
  1377.         descr = _("Keep the window under all other windows.");
  1378.         break;
  1379.      case 7:
  1380.         caption = _("Omnipresent");
  1381.         flag = WFLAGP(wwin, omnipresent);
  1382.         descr = _("Make window occupy all workspaces.");
  1383.         break;
  1384.      case 8:
  1385.         caption = _("Start Miniaturized");
  1386.         flag = WFLAGP(wwin, start_miniaturized);
  1387.         descr = _("Make the window be automatically miniaturized when it's\n"
  1388.             "first shown.");
  1389.         break;
  1390.      case 9:
  1391.         caption = _("Start Maximized");
  1392.         flag = WFLAGP(wwin, start_maximized!=0);
  1393.         descr = _("Make the window be automatically maximized when it's\n"
  1394.             "first shown.");
  1395.         break;
  1396.      case 10:
  1397.         caption = _("Skip Window List");
  1398.         flag = WFLAGP(wwin, skip_window_list);
  1399.         descr = _("Do not list the window in the window list menu.");
  1400.         break;
  1401.     }
  1402.     panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
  1403.     WMMoveWidget(panel->attrChk[i], 10, 20*(i+1));
  1404.     WMResizeWidget(panel->attrChk[i], frame_width-15, 20);
  1405.     WMSetButtonSelected(panel->attrChk[i], flag);
  1406.     WMSetButtonText(panel->attrChk[i], caption);
  1407.  
  1408.     WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
  1409.     }
  1410.  
  1411.  
  1412.     /**** more attributes ****/
  1413.     panel->moreFrm = WMCreateFrame(panel->win);
  1414.     WMSetFrameTitle(panel->moreFrm, _("Advanced"));
  1415.     WMMoveWidget(panel->moreFrm, 15, 45);
  1416.     WMResizeWidget(panel->moreFrm, frame_width, 250);
  1417.  
  1418.     for (i=0;
  1419. #ifdef XKB_BUTTON_HINT
  1420.      i < 9;
  1421. #else
  1422.      i < 8;
  1423. #endif
  1424.      i++) {
  1425.     char *caption = NULL;
  1426.     int flag = 0;
  1427.     char *descr = NULL;
  1428.     
  1429.     switch (i) {
  1430.      case 0:
  1431.         caption = _("Ignore HideOthers");
  1432.         flag = WFLAGP(wwin, no_hide_others);
  1433.         descr = _("Do not hide the window when issuing the\n"
  1434.               "`HideOthers' command.");
  1435.         break;
  1436.      case 1:
  1437.         caption = _("Don't Bind Keyboard Shortcuts");
  1438.         flag = WFLAGP(wwin, no_bind_keys);
  1439.         descr = _("Do not bind keyboard shortcuts from Window Maker\n"
  1440.               "when this window is focused. This will allow the\n"
  1441.               "window to receive all key combinations regardless\n"
  1442.               "of your shortcut configuration.");
  1443.         break;
  1444.      case 2:
  1445.         caption = _("Don't Bind Mouse Clicks");
  1446.         flag = WFLAGP(wwin, no_bind_mouse);
  1447.         descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
  1448.               "in the window (when alt is the modifier you have"
  1449.               "configured).");
  1450.         break;
  1451.      case 3:
  1452.         caption = _("Keep Inside Screen");
  1453.         flag = WFLAGP(wwin, dont_move_off);
  1454.         descr = _("Do not allow the window to move itself completely\n"
  1455.               "outside the screen. For bug compatibility.\n");
  1456.         break;
  1457.      case 4:
  1458.         caption = _("Don't Let It Take Focus");
  1459.         flag = WFLAGP(wwin, no_focusable);
  1460.         descr = _("Do not let the window take keyboard focus when you\n"
  1461.               "click on it.");
  1462.         break;
  1463.      case 5:
  1464.         caption = _("Don't Save Session");
  1465.         flag = WFLAGP(wwin, dont_save_session);
  1466.         descr = _("Do not save the associated application in the\n"
  1467.               "session's state, so that it won't be restarted\n"
  1468.               "together with other applications when Window Maker\n"
  1469.               "starts.");
  1470.         break;
  1471.      case 6:
  1472.         caption = _("Emulate Application Icon");
  1473.         flag = WFLAGP(wwin, emulate_appicon);
  1474.         descr = _("Make this window act as an application that provides\n"
  1475.               "enough information to Window Maker for a dockable\n"
  1476.               "application icon to be created.");
  1477.         break;
  1478.      case 7:
  1479.         caption = _("Full Screen Maximization");
  1480.         flag = WFLAGP(wwin, full_maximize);
  1481.         descr = _("Make the window use the whole screen space when it's\n"
  1482.               "maximized. The titlebar and resizebar will be moved\n"
  1483.               "to outside the screen.");
  1484.         break;
  1485. #ifdef XKB_BUTTON_HINT
  1486.      case 8:
  1487.         caption = _("Disable Language Button");
  1488.         flag = WFLAGP(wwin, no_language_button);
  1489.         descr = _("Remove the `toggle language' button of the window.");
  1490.         break;
  1491. #endif
  1492.     }
  1493.     panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
  1494.     WMMoveWidget(panel->moreChk[i], 10, 20*(i+1));
  1495.     WMResizeWidget(panel->moreChk[i], frame_width-15, 20);
  1496.     WMSetButtonSelected(panel->moreChk[i], flag);
  1497.     WMSetButtonText(panel->moreChk[i], caption);
  1498.  
  1499.     WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
  1500.     }
  1501.  
  1502.     /* miniwindow/workspace */
  1503.     panel->iconFrm = WMCreateFrame(panel->win);
  1504.     WMMoveWidget(panel->iconFrm, 15, 50);
  1505.     WMResizeWidget(panel->iconFrm,  PWIDTH - (2 * 15), 170);
  1506.     WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
  1507.  
  1508.     panel->iconLbl = WMCreateLabel(panel->iconFrm);
  1509.     WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 30);
  1510.     WMResizeWidget(panel->iconLbl, 64, 64);
  1511.     WMSetLabelRelief(panel->iconLbl, WRGroove);
  1512.     WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
  1513.     
  1514.     panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
  1515.     WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
  1516.     WMMoveWidget(panel->browseIconBtn, 22, 30);
  1517.     WMResizeWidget(panel->browseIconBtn, 100, 26);
  1518.     WMSetButtonText(panel->browseIconBtn, _("Browse..."));
  1519.  
  1520. #if 0
  1521.     panel->updateIconBtn = WMCreateCommandButton(panel->iconFrm);
  1522.     WMSetButtonAction(panel->updateIconBtn, (WMAction*)updateIcon, panel);
  1523.     WMMoveWidget(panel->updateIconBtn, 22, 65);
  1524.     WMResizeWidget(panel->updateIconBtn, 100, 26);
  1525.     WMSetButtonText(panel->updateIconBtn, _("Update"));
  1526. #endif
  1527. #ifdef wrong_behaviour
  1528.     WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
  1529.     pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
  1530.     WMSetButtonImage(panel->updateIconBtn, pixmap);
  1531.     WMReleasePixmap(pixmap);
  1532.     pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
  1533.     WMSetButtonAltImage(panel->updateIconBtn, pixmap);
  1534.     WMReleasePixmap(pixmap);
  1535. #endif
  1536.  
  1537.     panel->fileLbl = WMCreateLabel(panel->iconFrm);
  1538.     WMMoveWidget(panel->fileLbl, 20, 95);
  1539.     WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
  1540.     WMSetLabelText(panel->fileLbl, _("Icon File Name:"));
  1541.  
  1542.     panel->fileText = WMCreateTextField(panel->iconFrm);
  1543.     WMMoveWidget(panel->fileText, 20, 115);
  1544.     WMResizeWidget(panel->fileText, PWIDTH - (2 * 15) - (2 * 15), 20);
  1545.     WMSetTextFieldText(panel->fileText, NULL);
  1546.     WMAddNotificationObserver(textEditedObserver, panel, 
  1547.                   WMTextDidEndEditingNotification, 
  1548.                   panel->fileText);
  1549.     panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
  1550.     WMMoveWidget(panel->alwChk, 20, 140);
  1551.     WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 20);
  1552.     WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
  1553.     WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
  1554.  
  1555.  
  1556.     panel->wsFrm = WMCreateFrame(panel->win);
  1557.     WMMoveWidget(panel->wsFrm, 15, 225);
  1558.     WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
  1559.     WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
  1560.  
  1561.     WMSetBalloonTextForView(_("The workspace to place the window when it's"
  1562.                   "first shown."), WMWidgetView(panel->wsFrm));
  1563.  
  1564.     panel->wsP = WMCreatePopUpButton(panel->wsFrm);
  1565.     WMMoveWidget(panel->wsP, 20, 30);
  1566.     WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
  1567.     WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
  1568.     for (i = 0; i < wwin->screen_ptr->workspace_count; i++) {
  1569.     WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
  1570.     }
  1571.  
  1572.     i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance,
  1573.                                   wwin->wm_class);
  1574.     if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
  1575.     WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
  1576.     } else {
  1577.     WMSetPopUpButtonSelectedItem(panel->wsP, 0);
  1578.     }
  1579.  
  1580.     /* application wide attributes */
  1581.     if (wwin->main_window != None) {
  1582.     WApplication *wapp = wApplicationOf(wwin->main_window);
  1583.     
  1584.     panel->appFrm = WMCreateFrame(panel->win);
  1585.     WMSetFrameTitle(panel->appFrm, _("Application Wide"));
  1586.     WMMoveWidget(panel->appFrm, 15, 50);
  1587.     WMResizeWidget(panel->appFrm, frame_width, 240);
  1588.     
  1589.     for (i=0; i < 2; i++) {
  1590.         char *caption = NULL;
  1591.         int flag = 0;
  1592.         char *descr = NULL;
  1593.         
  1594.         switch (i) {
  1595.          case 0:
  1596.         caption = _("Start Hidden");
  1597.         flag = WFLAGP(wapp->main_window_desc, start_hidden);
  1598.         descr = _("Automatically hide application when it's started.");
  1599.         break;
  1600.          case 1:
  1601.         caption = _("No Application Icon");
  1602.         flag = WFLAGP(wapp->main_window_desc, no_appicon);
  1603.         descr = _("Disable the application icon for the application.\n"
  1604.               "Note that you won't be able to dock it anymore,\n"
  1605.               "and any icons that are already docked will stop\n"
  1606.               "working correctly.");
  1607.         break;
  1608.         }
  1609.         panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
  1610.         WMMoveWidget(panel->appChk[i], 10, 20*(i+1));
  1611.         WMResizeWidget(panel->appChk[i], 205, 20);
  1612.         WMSetButtonSelected(panel->appChk[i], flag);
  1613.         WMSetButtonText(panel->appChk[i], caption);
  1614.  
  1615.         WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
  1616.     }
  1617.     
  1618.     if (WFLAGP(wwin, emulate_appicon)) {
  1619.         WMSetButtonEnabled(panel->appChk[1], False);
  1620.         WMSetButtonEnabled(panel->moreChk[6], True);
  1621.     } else {
  1622.         WMSetButtonEnabled(panel->appChk[1], True);
  1623.         WMSetButtonEnabled(panel->moreChk[6], False);
  1624.     }
  1625.     } else {
  1626.     int tmp;
  1627.     
  1628.     if ((wwin->transient_for!=None && wwin->transient_for!=scr->root_win)
  1629.         || !wwin->wm_class || !wwin->wm_instance)
  1630.         tmp = False;
  1631.     else
  1632.         tmp = True;
  1633.     WMSetButtonEnabled(panel->moreChk[6], tmp);
  1634.  
  1635.     WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
  1636.     panel->appFrm = NULL;
  1637.     }
  1638.    
  1639.     /* if the window is a transient, don't let it have a miniaturize
  1640.      * button */
  1641.     if (wWindowFor(wwin->transient_for)!=NULL)
  1642.     WMSetButtonEnabled(panel->attrChk[3], False);
  1643.     else
  1644.     WMSetButtonEnabled(panel->attrChk[3], True);
  1645.  
  1646.     
  1647.     if (!wwin->wm_class && !wwin->wm_instance) {
  1648.     WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
  1649.     }
  1650.  
  1651.     
  1652.     WMRealizeWidget(panel->win);
  1653.  
  1654.     WMMapSubwidgets(panel->win);
  1655.     WMMapSubwidgets(panel->specFrm);
  1656.     WMMapSubwidgets(panel->attrFrm);
  1657.     WMMapSubwidgets(panel->moreFrm);
  1658.     WMMapSubwidgets(panel->iconFrm);
  1659.     WMMapSubwidgets(panel->wsFrm);
  1660.     if (panel->appFrm)
  1661.     WMMapSubwidgets(panel->appFrm);
  1662.  
  1663.     if (showSelectPanel) {
  1664.     WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
  1665.     changePage(panel->pagePopUp, panel);
  1666.     } else {
  1667.     WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
  1668.     changePage(panel->pagePopUp, panel);
  1669.     }
  1670.  
  1671.     
  1672.     parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 
  1673.                  0, 0, 0);
  1674.     XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
  1675.     panel->parent = parent;
  1676.     XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
  1677.  
  1678.     WMMapWidget(panel->win);
  1679.  
  1680.     XSetTransientForHint(dpy, parent, wwin->client_win);
  1681.  
  1682.     if (xpos == UNDEFINED_POS) {
  1683.     x = wwin->frame_x+wwin->frame->core->width/2;
  1684.     y = wwin->frame_y+wwin->frame->top_width*2;
  1685.     if (y + PHEIGHT > scr->scr_height)
  1686.         y = scr->scr_height - PHEIGHT - 30;
  1687.     if (x + PWIDTH > scr->scr_width)
  1688.         x = scr->scr_width - PWIDTH;
  1689.     } else {
  1690.     x = xpos;
  1691.     y = ypos;
  1692.     }
  1693.  
  1694.     panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, 
  1695.                      "Inspector", x, y, PWIDTH, PHEIGHT);
  1696.  
  1697.     if (!selectedBtn)
  1698.     selectedBtn = panel->defaultRb;
  1699.  
  1700.     WMSetButtonSelected(selectedBtn, True);
  1701.  
  1702.     selectSpecification(selectedBtn, panel);
  1703.  
  1704.     /* kluge to know who should get the key events */
  1705.     panel->frame->client_leader = WMWidgetXID(panel->win);
  1706.  
  1707.     WSETUFLAG(panel->frame, no_closable, 0);
  1708.     WSETUFLAG(panel->frame, no_close_button, 0);
  1709.     wWindowUpdateButtonImages(panel->frame);
  1710.     wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
  1711.     panel->frame->frame->on_click_right = destroyInspector;
  1712.  
  1713.     wWindowMap(panel->frame);
  1714.  
  1715.     showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, 
  1716.         wwin->wm_class, UPDATE_TEXT_FIELD);
  1717.  
  1718.     return panel;
  1719. }
  1720.  
  1721.  
  1722. void
  1723. wShowInspectorForWindow(WWindow *wwin)
  1724. {
  1725.     if (wwin->flags.inspector_open)
  1726.     return;
  1727.  
  1728.     WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
  1729.  
  1730.     make_keys();
  1731.     wwin->flags.inspector_open = 1;
  1732.     wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS,
  1733.                            UNDEFINED_POS, False);
  1734. }
  1735.  
  1736.  
  1737.  
  1738.     
  1739. void
  1740. wHideInspectorForWindow(WWindow *wwin)
  1741. {
  1742.     WWindow *pwin = wwin->inspector->frame;
  1743.  
  1744.     wWindowUnmap(pwin);
  1745.     pwin->flags.hidden = 1;
  1746.  
  1747.     wClientSetState(pwin, IconicState, None);
  1748. }
  1749.  
  1750.  
  1751.  
  1752. void
  1753. wUnhideInspectorForWindow(WWindow *wwin)
  1754. {
  1755.     WWindow *pwin = wwin->inspector->frame;
  1756.  
  1757.     pwin->flags.hidden = 0;
  1758.     pwin->flags.mapped = 1;
  1759.     XMapWindow(dpy, pwin->client_win);
  1760.     XMapWindow(dpy, pwin->frame->core->window);
  1761.     wClientSetState(pwin, NormalState, None);
  1762. }
  1763.  
  1764.  
  1765.  
  1766. WWindow*
  1767. wGetWindowOfInspectorForWindow(WWindow *wwin)
  1768. {    
  1769.     if (wwin->inspector) {
  1770.     assert(wwin->flags.inspector_open != 0);
  1771.     
  1772.     return wwin->inspector->frame;
  1773.     } else
  1774.     return NULL;
  1775. }
  1776.  
  1777.  
  1778. void
  1779. wCloseInspectorForWindow(WWindow *wwin)
  1780. {
  1781.     WWindow *pwin = wwin->inspector->frame; /* the inspector window */
  1782.  
  1783.     (*pwin->frame->on_click_right)(NULL, pwin, NULL);
  1784. }
  1785.  
  1786.  
  1787.